import os.path
import subprocess
import threading
import json
import time
from pyautogui import screenshot
import requests
from logger import logger
from datetime import datetime


def get_ip_list():
    ip_list = []
    with open('config.json', 'r') as fp:
        dic = json.load(fp)
        ip_list += dic.get("switch_ip_list")
        ip_list.append(dic.get("app_ip"))
        ip_list.append(dic.get("db_ip"))
        ip_list.append(dic.get("dns_ip"))
        url = dic.get("req_url")
        return ip_list, url


def record_error(msg):
    logger.error(msg)
    img = screenshot()
    now_time = datetime.now().strftime("%Y-%m-%d-%H-%M-%S")
    img.save(f'./img/{now_time}.png')


def do_ping(ip):
    res = subprocess.run(['ping', '-n', '2', '-l', '2000', '-w', '1000', ip], stdout=subprocess.PIPE)
    if res.returncode == 0:
        return True
    return False


class Pinger(threading.Thread):
    def __init__(self, ip):
        super(Pinger, self).__init__()
        self.daemon = True
        self.ip = ip
        self.finish = False
        self.result = False

    def run(self) -> None:
        while True:
            if self.finish is False:
                self.result = do_ping(self.ip)
                self.finish = True
            time.sleep(0.2)


if __name__ == '__main__':
    recover = False
    loss = False
    loss_start = 0
    if not os.path.exists('img'):
        os.mkdir('img')
    file = get_ip_list()
    ip_list = file[0]
    url = file[1]
    pinger_list = [Pinger(ip) for ip in ip_list]
    index = range(len(pinger_list))
    for i in index:
        pinger_list[i].start()

    while True:
        try:
            res = requests.get(url, timeout=1)
            # 掉线后正常恢复将recover进行置位
            if loss is True:
                loss = False
                recover = True
            # 当recover为True代表从断线状态恢复，统计掉线时间
            if recover is True:
                duration = int(time.time() - loss_start)
                minute = duration // 60
                second = duration - duration % 60 if duration > 60 else duration
                logger.error("="*10 + f"本次掉线持续{minute}分{second}秒" + "="*10)
                recover = False

            if res.status_code < 200 or res.status_code >= 300:
                record_error("服务器接口返回值异常")
            time.sleep(1)
        except Exception as e:
            # 出现掉线时将False置True
            if loss is False:
                loss_start = time.time()
            # 启用所有线程进行ping
            for i in index:
                pinger_list[i].finish = False
            ping_finish = False
            while not ping_finish:
                all_finish = [pinger_list[i].finish for i in index]
                ping_finish = all(all_finish)
                # 所有IP的ping结果都完成时执行结果判断
                if ping_finish:
                    all_result = [pinger_list[i].result for i in index]
                    # print("all result: ", all_result)
                    if all(all_result):
                        if loss is False:
                            record_error("服务器接口请求失败")
                            loss = True
                        continue
                    # 找出所有ping失败的ip
                    fail_list = []
                    for i in index:
                        if pinger_list[i].result is False:
                            fail_list.append(pinger_list[i].ip)
                    if loss is False:
                        record_error(f"网络异常：{fail_list}")
                        loss = True
